package cn.xiaolang.function.network.io;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Objects;

/**
 * @author Dean
 * @date 2022-01-15
 */
public class SocketServer {

    // =====> server socket listen properties
    private static final int S_RECEIVE_BUFFER = 10;
    private static final int S_SO_TIMEOUT = 0;
    private static final boolean S_REUSE_ADDR = false;
    // 连接等待队列大小
    private static final int S_BLACK_LOG = 2;

    // ======> client socket listen property on server endpoint
    private static final boolean C_KEEPALIVE = false;
    private static final boolean C_OOB = false;
    // Recv-Q & Send-Q
    private static final int C_RECV_BUF = 20;
    private static final boolean C_REUSE_ADDR = false;
    private static final int C_SEND_BUF = 20;
    // 启动socket等待
    private static final boolean C_LINGER = true;
    // socket等待最大秒数
    private static final int C_LINGER_MAX_SECOND = 0;
    private static final int C_TIMEOUT = 0;
    // 不延迟，接收立马处理
    private static final boolean C_NO_DELAY = false;


    public static void main(String[] args) {
        ServerSocket server = null;
        try {
            server = new ServerSocket(10010, S_BLACK_LOG);
            server.setReceiveBufferSize(S_RECEIVE_BUFFER);
            server.setReuseAddress(S_REUSE_ADDR);
            server.setSoTimeout(S_SO_TIMEOUT);
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println("server up use port:" + 10010);

        while (true) {
            try {
                // read 系统调用阻塞
                System.in.read();

                //执行到此处时，程序处于阻塞状态，直到客户端连接，转为运行状态
                Socket client = Objects.requireNonNull(server).accept();
                System.out.println("client port:" + client.getPort());

                client.setKeepAlive(C_KEEPALIVE);
                client.setOOBInline(C_OOB);
                client.setReceiveBufferSize(C_RECV_BUF);
                client.setReuseAddress(C_REUSE_ADDR);
                client.setSendBufferSize(C_SEND_BUF);
                client.setSoLinger(C_LINGER, C_LINGER_MAX_SECOND);
                client.setTcpNoDelay(C_NO_DELAY);

                new Thread(() -> {
                    while (true) {

                        try {
                            InputStream in = client.getInputStream();
                            BufferedReader br = new BufferedReader(new InputStreamReader(in));
                            char[] data = new char[1024];
                            int num = br.read(data);
                            if (num > 0) {
                                System.out.println("client read some data " + num + "(bit):" + new String(data, 0, num));
                            } else if (num == 0) {
                                System.out.println("client read nothing!");
                            } else {
                                System.out.println("client read close:" + client.getPort());
                                client.close();
                                break;
                            }

                        } catch (IOException e) {
                            e.printStackTrace();
                        }

                    }
                }).start();

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


}
